<?php

namespace App\Http\Controllers;

use App\Library\Logic\PaymentRelatedLogic;
use App\Library\Requests\Base\SerialNumberRequest;
use App\Library\Service\WechatService;
use App\Library\YsdLib;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Psr\Http\Message\ResponseInterface;
use Yansongda\Artful\Exception\ContainerException;
use Yansongda\Artful\Exception\InvalidParamsException;
use Yansongda\Artful\Exception\ServiceNotFoundException;
use Yansongda\Artful\Rocket;
use Yansongda\Pay\Pay;
use Yansongda\Supports\Collection;

class WechatController extends BaseController
{

    /**
     * @throws ContainerException
     */
    public function __construct(WechatService $service)
    {
        Pay::config(YsdLib::config());
        $this->service = $service;
    }

    /**
     * 保证金退款回调
     * @return JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function auctionBailRefund(): JsonResponse
    {
        return $this->service->auctionBailRefund();
    }

    /**
     * 直播保证金退回
     * @return JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function zbBailRefund(): JsonResponse
    {
        return $this->service->zbBailRefund();
    }

    /**
     * 售后退款回调
     * @return JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function afterSaleRefund(): JsonResponse
    {
        return $this->service->afterSaleRefund();
    }

    /**
     * 退款查询
     * Collection|Rocket
     * @throws ContainerException|ContainerException|InvalidParamsException|ServiceNotFoundException
     */
    public function wechatRefundQuery(): Collection|Rocket
    {
        return Pay::wechat()->query([
            'out_refund_no' => request()->post('outRefundNo'),
            '_action' => 'refund',
        ]);
    }

    /**
     * 提现回调
     * @return JsonResponse
     */
    public function notifyWithdraw(): JsonResponse
    {
        payLog(request()->post());
        return success();
    }

    /**
     * notify
     * @return ResponseInterface
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function notify(): ResponseInterface
    {
        return $this->service->notify();
    }

    /**
     * notifyRefund
     * @return ResponseInterface
     * @throws Exception
     */
    public function notifyRefund(): ResponseInterface
    {
        return $this->service->notifyRefund();
    }

    /**
     * return
     * @return JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function return(): JsonResponse
    {
        $transactionId = request()->post('transactionId');
        $payment = DB::table('payment')->where('out_trade_no', $transactionId)->first();
        if (is_null($payment)) return failMessage('订单号不存在');
        $find = json_decode($payment->find, true);
        return success(Pay::wechat()->refund([
            'transaction_id' => $transactionId,
            'out_trade_no' => $find['out_trade_no'],
            'out_refund_no' => $payment->serial_number,
            'reason' => 'viki-test',
            'amount' => [
                'refund' => 1,
                'total' => 1,
                'currency' => 'CNY',
            ],
        ]));
    }

    /**
     * query
     * @param SerialNumberRequest $request
     * @return Collection|Rocket|JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function query(SerialNumberRequest $request): Collection|Rocket|JsonResponse
    {
        $paymentRelated = PaymentRelatedLogic::findBySerialNumber($request);
        if (is_null($paymentRelated)) return fail();
        return Pay::wechat(YsdLib::configByModel($paymentRelated))->query([
            '_action' => 'mini',
            'out_trade_no' => $paymentRelated->serial_number,
        ]);
    }
}
